using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using Weight.Base;

namespace JHVideo
{
    class HkVideo : IVideo
    {
        /// <summary>
        /// 初始化状态
        /// </summary>
        private bool m_bInitSDK = false;

        /// <summary>
        /// 登录状态
        /// </summary>
        private Int32 m_lUserID = -1;

        /// <summary>
        /// 每个通道的句柄
        /// </summary>
        private List<int> mHandle = new List<int>();

        /// <summary>
        /// 默认摄像头的数量
        /// </summary>
        public int mCount = 2;


        /// <summary>
        ///初始化
        /// </summary>
        /// <param name="VideoCount">视频数量</param>
        /// <returns></returns>
        public ResultEntity Init()
        {
            var result = ResultEntity.Default();
            try
            {
                m_bInitSDK = CHCNetSDK.NET_DVR_Init();
                if (m_bInitSDK == false)
                {
                    result = ResultEntity.Error();
                }
                else
                {
                    string path = Environment.CurrentDirectory + "\\videoLog";
                    CHCNetSDK.NET_DVR_SetLogToFile(3, path, true);
                    result = ResultEntity.Success("海康监控 SDK 初始化成功!");
                }
            }
            catch (Exception ex)
            {
                result = ResultEntity.Error("海康监控SDK 初始化异常:" + ex.Message + ex.StackTrace);
            }
            return result;
        }

        /// <summary>
        /// 登录硬盘录像机
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public ResultEntity Login(LoginEntity model)
        {
            var rs = ResultEntity.Default();
            try
            {
                string DVRIPAddress = model.IP; //设备IP地址或者域名
                Int16 DVRPortNumber = model.Port;//设备服务端口号
                string DVRUserName = model.Account;//设备登录用户名
                string DVRPassword = model.Pwd;//设备登录密码

                logOut(); //先退出登录
                CHCNetSDK.NET_DVR_DEVICEINFO_V30 DeviceInfo = new CHCNetSDK.NET_DVR_DEVICEINFO_V30();
                m_lUserID = CHCNetSDK.NET_DVR_Login_V30(DVRIPAddress, DVRPortNumber, DVRUserName, DVRPassword, ref DeviceInfo);
                if (m_lUserID < 0)
                {
                    uint iLastErr = CHCNetSDK.NET_DVR_GetLastError();
                    rs = ResultEntity.Error("录像登录失败, error code= " + iLastErr);
                }
                else
                {
                    rs = ResultEntity.Success("海康监控登录成功!");
                }
            }
            catch (Exception ex)
            {
                rs = ResultEntity.Error("录像机登录异常:" + ex.Message + ex.StackTrace);
            }

            return rs;
        }


        /// <summary>
        /// 预览
        /// </summary>
        /// <returns></returns>
        public ResultEntity Play(List<ChannelEntity> Channels)
        {
            var rs = ResultEntity.Default();
            try
            {
                if (m_lUserID < 0)
                {
                    rs = ResultEntity.Error("硬盘录像机登录失败，预览失败\r\n");
                    return rs;
                }
                if (Channels == null || Channels.Count == 0)
                {
                    rs = ResultEntity.Error("硬盘录像机无通道参数，预览失败\r\n");
                    return rs;
                }

                StopPlay(); //停止当前预览的通道

                ///开始预览
                StringBuilder msgBuider = new StringBuilder();
                ChannelEntity item;
                mHandle.Clear();
                for (int index = 0; index < Channels.Count; index++)
                {
                    mHandle.Add(-1);
                    item = Channels[index];
                    if (item == null || item.Handle == null || item.ChannelNo < 0)
                    {
                        if (item != null) msgBuider.Append("通道号:" + item.ChannelNo + " 参数配置非法;\r\n ");
                        continue;
                    }
                    CHCNetSDK.NET_DVR_PREVIEWINFO lpPreviewInfo = new CHCNetSDK.NET_DVR_PREVIEWINFO();
                    lpPreviewInfo.hPlayWnd = item.Handle;//预览窗口
                    lpPreviewInfo.lChannel = item.ChannelNo;//预te览的设备通道
                    lpPreviewInfo.dwStreamType = 0;//码流类型：0-主码流，1-子码流，2-码流3，3-码流4，以此类推
                    lpPreviewInfo.dwLinkMode = 0;//连接方式：0- TCP方式，1- UDP方式，2- 多播方式，3- RTP方式，4-RTP/RTSP，5-RSTP/HTTP 
                    lpPreviewInfo.bBlocked = true; //0- 非阻塞取流，1- 阻塞取流

                    CHCNetSDK.REALDATACALLBACK RealData = new CHCNetSDK.REALDATACALLBACK(RealDataCallBack);//预览实时流回调函数
                    IntPtr pUser = new IntPtr();//用户数据

                    //打开预览 Start live view 
                    mHandle[index] = CHCNetSDK.NET_DVR_RealPlay_V40(m_lUserID, ref lpPreviewInfo, null/*RealData*/, pUser);
                    if (mHandle[index] < 0)
                    {
                        uint errorCode = CHCNetSDK.NET_DVR_GetLastError();
                        msgBuider.Append("通道号" + item.ChannelNo + " 预览失败，错误编码:" + errorCode).Append(";\r\n");
                    }
                }

                rs = ResultEntity.Success(msgBuider.ToString());

            }
            catch (Exception ex)
            {
                rs = ResultEntity.Error("通道预览异常:" + ex.Message + ex.StackTrace+"\r\n");
            }

            return rs;
        }

        public void RealDataCallBack(Int32 lRealHandle, UInt32 dwDataType, ref byte pBuffer, UInt32 dwBufSize, IntPtr pUser)
        {

        }
        public static void RealDataCallBack(Int32 lRealHandle, UInt32 dwDataType, IntPtr pBuffer, UInt32 dwBufSize, IntPtr pUser)
        {

        }

        /// <summary>
        /// 停止通道预览
        /// </summary>
        /// <returns></returns>
        public ResultEntity StopPlay()
        {
            var rs = ResultEntity.Default();
            try
            {
                bool b = true;
                StringBuilder ContentBuider = new StringBuilder();
                for (int index = 0; index < mHandle.Count; index++)
                {
                    if (mHandle[index] >= 0)
                    {
                        //停止预览 
                        if (!CHCNetSDK.NET_DVR_StopRealPlay(mHandle[index]))
                        {
                            uint code = CHCNetSDK.NET_DVR_GetLastError();
                            b = false;
                            ContentBuider.Append("通道停止预览出错, error code= " + code).Append(";");
                        }
                        mHandle[index] = -1;
                    }
                }

                if (b)
                {
                    rs = ResultEntity.Success("通道停止预览成功");
                }
                else
                {
                    rs = ResultEntity.Error(ContentBuider.ToString());
                }
            }
            catch (Exception ex)
            {
                rs = ResultEntity.Error("停止通道预览异常:" + ex.Message + ex.StackTrace);
            }
            return rs;
        }


        /// <summary>
        /// 抓拍图片
        /// </summary>
        /// <param name="path"></param>
        public ResultEntity CaptureImg(CaptureParamEntity entity)
        {
            Thread task = new Thread(new ParameterizedThreadStart (CaptureImgTask)) { IsBackground = true };
            task.Start(entity);
            return ResultEntity.Success("调用抓拍图片功能成功!");
        }


        /// <summary>
        /// 抓拍图片任务
        /// </summary>
       private void CaptureImgTask(object obj)
        {
            CaptureParamEntity entity = obj as CaptureParamEntity;
            if (entity == null) return;
            StringBuilder MsgBuider = new StringBuilder();
            Dictionary<string, bool> ImgIsExist = new Dictionary<string, bool>();
            for (int i = 0; i < mHandle.Count; i++)
            {
                try
                {
                    int handler = mHandle[i];
                    if (entity.Path.Length== 0) return;
                    if (!Directory.Exists(entity.Path)) Directory.CreateDirectory(entity.Path);
                    string fileName = entity.Path + "\\" + entity.Prefix + "_" + i.ToString() + ".jpg";
                    if (fileName.Contains("\\\\")) fileName.Replace("\\\\","\\");
                    if (fileName.Contains("//")) fileName.Replace("//","/");
                    if (File.Exists(fileName)) File.Delete(fileName);
                    if (!CHCNetSDK.NET_DVR_CapturePicture(handler, fileName))
                    {
                        uint iLastErr = CHCNetSDK.NET_DVR_GetLastError();
                        MsgBuider.Append("抓拍BMP图片出错, error code= " + iLastErr).Append("; 路径:")
                            .Append(fileName);
                    }
                    else
                    {
                        ImgIsExist.Add(fileName,false);
                    }
                    
                }
                catch (Exception ex)
                {
                    MsgBuider.Append("抓拍图片异常:"+ex.Message+ex.StackTrace);
                    continue;
                }
            }


            List<string> successList = new List<string>();
            List<string> Keys = new List<string>(ImgIsExist.Keys);
            ImageHandler imgHander = new ImageHandler();
            try
            {
                int index = 0;
                while (index < 10)
                {
                    for (int i=0; i< Keys.Count; i++ )
                    {
                        if (File.Exists(Keys[i]) )
                        {
                            if (!ImgIsExist[Keys[i]])
                            {
                                if (entity.Ratio != 100)
                                {
                                    ResultEntity result = imgHander.CompressImg(Keys[i], entity.Ratio);
                                    if (result.State != 1)
                                    {
                                        MsgBuider.Append(result.Message);
                                    }
                                }

                                if (entity.DrawingParam != null)
                                {
                                    entity.DrawingParam.Path = Keys[i];
                                    ResultEntity result = imgHander.DrawString(entity.DrawingParam);
                                    if (result.State != 1)
                                    {
                                        MsgBuider.Append(result.Message);
                                    }
                                }
                                successList.Add(Keys[i]);
                                ImgIsExist[Keys[i]] = true;
                            }
                        }
                        else
                        {
                            Thread.Sleep(300);
                        }
                    }

                    foreach(bool item in ImgIsExist.Values)
                    {
                        if(!item)
                        {
                            Thread.Sleep(200);
                            break;
                        }
                    }
                    index++;
                }
              
            }
            catch(Exception ex)
            {
                MsgBuider.Append("处理图片异常:" + ex.Message + ex.StackTrace);
            }

            if (entity.CallBack != null)
            {
                entity.CallBack(entity.Id, MsgBuider.ToString(), successList);
            }
        }



        /// <summary>
        /// 停止预览和注销
        /// </summary>
        public ResultEntity logOut()
        {
            var rs = ResultEntity.Default();
            try
            {
                if (m_lUserID >= 0)
                {
                    if (!CHCNetSDK.NET_DVR_Logout(m_lUserID))
                    {
                        uint code = CHCNetSDK.NET_DVR_GetLastError();
                        rs = ResultEntity.Error("硬盘录像机注销失败, error code= " + code);
                    }
                    else
                    {
                        rs = ResultEntity.Success("硬盘录像机登录注销成功");
                    }
                    m_lUserID = -1;
                }
                else
                {
                    rs = ResultEntity.Success("非登陆状态，不能注销");
                }
            }
            catch (Exception ex)
            {
                rs = ResultEntity.Error("硬盘录像机注销异常:" + ex.Message + ex.StackTrace);
            }

            return rs;
        }


        /// <summary>
        /// 关闭
        /// </summary>
        public ResultEntity Close()
        {
            var rs = ResultEntity.Default();
            try
            {
                var stopRs = StopPlay();
                var logOutRs = logOut();
                rs = ResultEntity.Success("停止预览:" + stopRs.Message + "; 注销登录" + logOutRs.Message);
            }
            catch (Exception ex)
            {
                rs = ResultEntity.Error("硬盘录像机关闭异常:" + ex.Message + ex.StackTrace);
            }
            return rs;
        }
    }
}


